package yartiss.service.model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;

import yartiss.engine.simulation.energy.profiles.consumption.ConsumptionProfileFactory;
import yartiss.engine.simulation.system.ITask;
import yartiss.engine.simulation.system.schedulable.SchedulableFactory;

@SuppressWarnings("serial")
public class TasksTableModel extends AbstractTableModel {

	private List<Object []> tasks = new LinkedList<Object[]>();
	private String [] columnsNames = new String []{"Type", "r0","Ci", "Ei" , "Ti", "Di", "Pi", "Cons type"};
	private boolean showEi = false;
	private int prio = 1;
	private boolean showConsType =  false;
	
	@Override
	public int getRowCount() {
		return tasks.size();
	}

	@Override
	public int getColumnCount() {
		int ei = showEi ? 1 : 0;
		int cons = showConsType ? 1 : 0;
		
		return 6 + ei+cons;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		Object [] task = tasks.get(rowIndex);
		return task[columnIndex];
	}
	
	@Override
	public void setValueAt(Object value, int rowIndex, int columnIndex) {
		Object [] task = tasks.get(rowIndex);
		Object oldValue = task[columnIndex];
		try {
			task[columnIndex] = value;
			SchedulableFactory.newInstance(task[0].toString(),task[1],task[2],task[3],task[4],task[5],task[6],task[7]);
		}
		catch (Exception e) {
			task[columnIndex] = oldValue;
		}
		fireTableChanged(new TableModelEvent(this));
	}
	
	@Override
	public boolean isCellEditable(int row, int col) {
		return true;
	}
	
	public Object [] getRow(int rowIndex){
		return tasks.get(rowIndex);
	}
	
	public void addRow(ITask task){
		addRow(task.getType(), task.getFirstRelease(), task.getWcet(), task.getWcee(), task.getPeriod(), task.getDeadline(), task.getPriority(), task.getEnergyConsumptionProfile().getName());
	}
	
	public ITask getTask(int rowIndex){
		Object [] row = getRow(rowIndex);
		return SchedulableFactory.newInstance(row[0].toString(),row[1],row[2],row[3],row[4],row[5],row[6],row[7]);
	}
	
	public void addRow(Object ... row){
		Object [] task =Arrays.copyOf(row, 8);
		if(task[7]==null)task[7] = getConsumptionFrofiles()[0];
		tasks.add(task);
		fireTableDataChanged();
	}
	
	
	public void addRow(){
		addRow(getSchedulablesTypes()[0],0,1,1,1,1,prio++,getConsumptionFrofiles()[0]);
	}
	
	public void addAll(ITask [] tasksToAdd){
		for (ITask task : tasksToAdd) {
			tasks.add(new Object[]{task.getType(), task.getFirstRelease(), task.getWcet(), task.getWcee(), task.getPeriod(), task.getDeadline(), task.getPriority(), task.getEnergyConsumptionProfile().getName()});
		}
		fireTableDataChanged();
	}
	
	public void removeRow(int rowIndex){
		tasks.remove(rowIndex);
		fireTableDataChanged();
	}
	
	public List<Object[]> getAllItems(){
		return new ArrayList<Object[]>(tasks);
	}
	
	public List<ITask> getAllTasks(){
		List<ITask> allTasks = new ArrayList<ITask>();
		for (int i = 0; i < tasks.size(); i++) {
			allTasks.add( getTask(i) );
		}
		return allTasks;
	}
	
	public String [] getSchedulablesTypes(){
		return SchedulableFactory.availableTypes;
	}
	
	public String [] getConsumptionFrofiles(){
		return ConsumptionProfileFactory.getAvailableProfiles();
	}
	
	public void clear(){
		prio = 1;
		tasks.clear();
		fireTableDataChanged();
	}
	
	public void setConsProfileVisible(boolean bool){
		showConsType = bool;
		fireTableStructureChanged();
	}
	
	
	
	@Override
	public String getColumnName(int columnIndex){
		if(columnIndex > 2 &&  !showEi)columnIndex++;
		return columnsNames[columnIndex];
	}
	
	@Override
	public Class<?> getColumnClass(int column) {
		switch (column) {
		case 0: return String.class;
		case 1: return Integer.class;
		case 2: return Integer.class;
		case 3: return Integer.class;
		case 4 : return Integer.class;
		case 5 : return Integer.class;
		case 6:	return  Integer.class;
		case 7:	return String.class;
		}
		return Object.class;
	}

	public void setEnergyCostVisivble(boolean b) {
		showEi = b;
		showConsType = b;
		fireTableStructureChanged();
	}

}
